/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package client;


import com.*;
import chat.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.DatagramPacket;
/**
 *
 * @author michaellangmayr
 */
public class ClientListener extends Thread {
    private UDPChatClient chatClient = null;

    public ClientListener(UDPChatClient chatClient) throws java.net.SocketException {
        this.chatClient = chatClient;
    }

    @Override
    public void run(){
        while (true) {
            byte[] buf = new byte[0xFFFF];
            DatagramPacket packet = new DatagramPacket(buf, buf.length);
            try {
                chatClient.getSocket().receive(packet);
            } catch (IOException ex) {
                System.err.println("[ClientListener] Socket error: " + ex);
                continue;
            }

            ByteArrayInputStream bis = new ByteArrayInputStream(packet.getData());
            ObjectInputStream in;
            ReliableDatagram relDataRcvd = null;
            try {
                in = new ObjectInputStream(bis);
                relDataRcvd = (ReliableDatagram)in.readObject();
            } catch (IOException ex) {
                System.err.println("Couldn't read stream " + ex);
                continue;
            } catch (ClassNotFoundException ex) {
                System.err.println("Couldn't cast stream object " + ex);
                continue;
            }

            int inSequNr = relDataRcvd.getSequenceNumber();
            int expectedSequNr = chatClient.getSequData().getInSequNr() + 1;
            if (inSequNr < expectedSequNr && inSequNr > 0) {
                System.err.println("----> duplicate PACKET received SequNr: " + inSequNr + " expected: " + expectedSequNr + " <----");
                continue;
            } else if (inSequNr > expectedSequNr) {
                System.err.println("----> missing PACKETs. Received SequNr: " + inSequNr + " expected: " + expectedSequNr + " <----");
            }
            chatClient.getSequData().setInSequNr(inSequNr);

            ChatCommand relDataRcvdCmd = (ChatCommand)relDataRcvd.getData();
            if (relDataRcvdCmd == null) {
                System.err.println("[ClientListener] received packet that doesn't contain a ChatCommand: sequNr " + relDataRcvd.getSequenceNumber() +
                    " data type " + relDataRcvd.getData().getClass());
            } else {
                System.out.println("[ClientListener] cmd with sequNr " + inSequNr + " cmdType " + relDataRcvdCmd.getCommand() +
                    " msgId " + relDataRcvdCmd.getMsgId());
                switch (relDataRcvdCmd.getCommand()) {
                    case CONFIRMNICKNAME:
                        chatClient.getView().writeServerResponse("Nickname confirmed");
                        chatClient.getView().confirmNickname();
                        break;
                    case REFUSENICKNAME:
                        chatClient.getView().writeServerResponse("Nickname refused! Please try another Nickname.");
                        break;
                    case SENDMSG:
                        chatClient.getView().writeMessage(relDataRcvdCmd.getChatMsg());
                        chatClient.setMsgId(relDataRcvdCmd.getMsgId() + 1);
                        break;
                    default:
                        System.err.println("[ClientListener] unexpected cmd received " + relDataRcvdCmd.getCommand());
                }
            }
        }
    }

}
